use crate::{
    config::SourceSite,
    error::{HelperError, Result},
    tui::ui::TableData,
};
use ratatui::widgets::Row;
use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize)]
pub(crate) struct LibLibAiModelInfo {
    pub id: u32,
    pub user_id: u32,
    pub name: String,
    pub model_type: String,
    pub base_type: String,
    pub uuid: String,
    pub image_url: String,
    pub nickname: String,
    pub audit_time: String,
}

impl<'a> TableData<'a> for LibLibAiModelInfo {
    type Data = Self;
    type TableData = Row<'a>;

    fn data(&self) -> &Self::Data {
        &self
    }

    fn to_table_data(&self) -> Self::TableData {
        Row::new(vec![
            self.name.clone(),
            self.model_type.clone(),
            self.base_type.to_string(),
            "".to_string(),
            "".to_string(),
            SourceSite::Liblibai.to_string(),
        ])
    }
}

#[derive(Debug, Deserialize)]
pub(crate) struct LibLibAiModelList {
    pub page: u32,
    pub total: u32,
    pub page_size: u32,
    pub data: Vec<LibLibAiModelInfo>,
}

#[derive(Debug, Serialize)]
pub(crate) struct LibLibAiModelListRequest {
    pub cid: String,
    pub page: u16,
    pub page_size: u16,
    pub sort: u8,
    pub tag_v2_id: Option<String>,
    pub types: Vec<u8>,
    pub models: Vec<u8>,
}

#[derive(Debug, Deserialize)]
pub(crate) struct LibLibAiResponse {
    pub code: u32,
    pub msg: String,
    pub data: LibLibAiModelList,
}

static LIBLIBAI_SEARCH_URL: &str = "https://liblib-api.vibrou.com/api/www/model/search";

pub(crate) async fn get_model_vec(request: LibLibAiModelListRequest) -> Result<LibLibAiModelList> {
    let client = reqwest::Client::new();
    match client.post(LIBLIBAI_SEARCH_URL).json(&request).send().await {
        Ok(r) => match r.json::<LibLibAiResponse>().await {
            Ok(LibLibAiResponse { code: 0, data, .. }) => Ok(data),
            Ok(LibLibAiResponse { code, msg, .. }) => Err(HelperError::LibLibAiApi {
                code,
                msg: msg.to_string(),
            }),
            Err(e) => Err(HelperError::Http(e)),
        },
        Err(e) => Err(HelperError::Http(e)),
    }
}
